---
title: Create a project
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import HeaderLabel from '@site/src/components/Docs/HeaderLabel';
import NextSteps from '@site/src/components/NextSteps';
import LangPartials from '@site/src/components/LangPartials';

<HeaderLabel text="3 min" />

With a [workspace](./setup-workspace), we can now house one or many [projects](./concepts/project),
with a project being an application, library, or tool. In the end, each project will have its own
build layer, personal tasks, and custom configuration.

## Declaring a project in the workspace

Although a project may exist in your repository, it's not accessible from moon until it's been
mapped in the [`projects`](./config/workspace#projects) setting found in
[`.moon/workspace.yml`](./config/workspace). When mapping a project, we require a unique name for
the project, and a project source location (path relative from the workspace root).

Let's say we have a frontend web application called "client", and a backend application called
"server", our `projects` setting would look like the following.

```yaml title=".moon/workspace.yml"
projects:
  client: 'apps/client'
  server: 'apps/server'
```

We can now run [`moon project client`](./commands/project) and
[`moon project server`](./commands/project) to display information about each project. If these
projects were not mapped, or were pointing to an invalid source, the command would throw an error.

:::success

The [`projects`](./config/workspace#projects) setting also supports a list of globs, if you'd prefer
to not manually curate the projects list!

:::

## Configuring a project

A project can be configured in 1 of 2 ways:

- Through the [`.moon/tasks.yml`](./config/tasks) config file, which defines file groups and tasks
  that are inherited by _all_ projects within the workspace. Perfect for standardizing common tasks
  like linting, typechecking, and code formatting.
- Through the [`moon.yml`](./config/project) config file, found at the root of each project, which
  defines files groups, tasks, dependencies, and more that are unique to that project.

Both config files are optional, and can be used separately or together, the choice is yours!

Now let's continue with our client and server example above. If we wanted to configure both
projects, and define config that's also shared between the 2, we could do something like the
following:

<Tabs
  groupId="project-config"
  defaultValue="client"
  values={[
    { label: 'Client', value: 'client' },
    { label: 'Server', value: 'server' },
    { label: 'Both (inherited)', value: 'inherit' },
  ]}
>
<TabItem value="client">

```yaml title="apps/client/moon.yml"
tasks:
  build:
    command: 'vite dev'
    inputs:
      - 'src/**/*'
    outputs:
      - 'dist'
```

</TabItem>
<TabItem value="server">

```yaml title="apps/server/moon.yml"
tasks:
  build:
    command: 'babel src --out-dir build'
    inputs:
      - 'src/**/*'
    outputs:
      - 'build'
```

</TabItem>
<TabItem value="inherit">

```yaml title=".moon/tasks.yml"
tasks:
  format:
    command: 'prettier --check .'
  lint:
    command: 'eslint --no-error-on-unmatched-pattern .'
  test:
    command: 'jest --passWithNoTests .'
  typecheck:
    command: 'tsc --build'
```

</TabItem>
</Tabs>

### Adding optional metadata

When utilizing moon in a large monorepo or organization, ownership becomes very important, but also
difficult to maintain. To combat this problem, moon supports the
[`project`](./config/project#project) field within a project's [`moon.yml`](./config/project)
config.

This field is _optional_ by default, but when defined it provides metadata about the project,
specifically around team ownership, which developers maintain the project, where to discuss it, and
more!

Furthermore, we also support the [`layer`](./config/project#layer) and
[`language`](./config/project#language) settings for a more granular breakdown of what exists in the
repository.

```yaml title="<project>/moon.yml"
layer: 'tool'
language: 'typescript'

project:
  name: 'moon'
  description: 'A repo management tool.'
  channel: '#moon'
  owner: 'infra.platform'
  maintainers: ['miles.johnson']
```

## Next steps

<NextSteps
  links={[
    { icon: 'toolchain', label: 'Setup toolchain', url: './setup-toolchain' },
    {
      icon: 'workspace-config',
      label: (
        <span>
          Configure <code>.moon/workspace.yml</code> further
        </span>
      ),
      url: './config/workspace',
    },
    {
      icon: 'project-config-global',
      label: (
        <span>
          Configure <code>.moon/tasks.yml</code> further
        </span>
      ),
      url: './config/tasks',
    },
    {
      icon: 'project-config',
      label: (
        <span>
          Configure <code>moon.yml</code> further
        </span>
      ),
      url: './config/project',
    },
    { icon: 'project', label: 'Learn about projects', url: './concepts/project' },
  ]}
/>
